﻿#include "XEYYJSON.h"
#include "string"

YYJSONH::YYJSONH(){
	Create();
}
YYJSONH::YYJSONH(const char*str) {
	Create(str);
}
YYJSONH::~YYJSONH() {
	Clear();
}

void YYJSONH::Clear() {
	yyjson_doc_free(m_rootDoc);
}

YYJSONH& YYJSONH::Create(const char*json) {
	if (m_rootDoc != NULL) {
		Clear();
	}
	if (json == NULL || json =="") {
		m_rootDoc = yyjson_read("{}", 2, 0);
		m_rootDom = yyjson_doc_get_root(m_rootDoc);
		return *this;
	}
	m_rootDoc = yyjson_read(json, strlen(json), 0);
	m_rootDom = yyjson_doc_get_root(m_rootDoc);
	return *this;
}

YYJSONH& YYJSONH::Parse(const char* json) {
	if (m_rootDoc != NULL) {

	}
	if (json == NULL || json == "") {
		m_rootDoc = yyjson_read("{}", 2, 0);
		return *this;
	}
	return *this;
}

const char* YYJSONH::GetString(const char*path) {
	yyjson_val* ret = PathParsed(m_rootDom, path);
	if (ret != NULL){
		const char* r = yyjson_get_str(ret);
		return r == NULL ? "": r;
	}
	return "";
};



//@ 由路径取对应节点
yyjson_val* YYJSONH::PathParsed(yyjson_val* root, const char* path) {
	std::string stpath = path;
	if (path == NULL) {
		return root;
	}
	size_t StrLen			///< 路径长度
		= stpath.length();
	if (StrLen == 0) {
		return root;
	}

	size_t OldSubscript		///< 上一个标记点位置
		= 0;
	size_t pos		///< 标记点当前位置
		= 0;
	bool inArray = false;		///< 上一个标记点是否是数组头 [
	yyjson_val* ctmp = root;
	bool hasName = false;
	bool hasIndex = true;
	size_t namePos = 0, nameLen, indexPos = 0;

	while (pos <= StrLen)
	{
		char wchar = stpath[pos];
		if (wchar == '\\') {
			char nextchar = stpath[pos + 1];
			if (nextchar == '.'
				|| nextchar == '['
				|| nextchar == ']'
				|| nextchar == '\\'
				) {
				stpath.erase(pos, 1);
				--StrLen;
			}
		}
		else if (wchar == '.' || pos == StrLen)	//.或者结尾
		{
			hasName = namePos < pos;
			if (hasName) {
				nameLen = pos - namePos;
				//printf( ".:%s\n", stpath.substr(namePos, nameLen).c_str());
				ctmp = yyjson_obj_get(ctmp, stpath.substr(namePos, nameLen).c_str());
				//ctmp = cJSON_GetObjectItem(ctmp, stpath.substr(namePos, nameLen).c_str());
			}
			namePos = pos + 1;
		}
		else if (wchar == '[')
		{
			indexPos = pos + 1;
			hasIndex = true;
			hasName = namePos < pos;
			if (hasName) {
				nameLen = pos - namePos;
				//printf("[:%s\n", stpath.substr(namePos, nameLen).c_str());
				//auto t = yyjson_arr_get();

				ctmp = yyjson_obj_get(ctmp, stpath.substr(namePos, nameLen).c_str());
				//ctmp = cJSON_GetObjectItem(ctmp, stpath.substr(namePos, nameLen).c_str());
			}
			namePos = pos + 1;
		}
		else if (wchar == ']')
		{
			if (hasIndex) {
				nameLen = pos - indexPos;
				//printf("]:%d\n", atoi(stpath.substr(namePos, nameLen).c_str()));
				yyjson_arr_get(ctmp, atoi(stpath.substr(namePos, nameLen).c_str()));
				//ctmp = cJSON_GetArrayItem(ctmp, atoi(stpath.substr(namePos, nameLen).c_str()));
			}
			namePos = pos + 1;
		}
		else {
			++pos;
			continue;
		}

		if (ctmp == NULL) {
			return NULL;
		}
		++pos;
		//OldSubscript = Subscript;

	}
	return ctmp;
}